package org.barad.architecture.analyzer.archpad.component;

import java.awt.Color;
import java.util.Iterator;
import java.util.NoSuchElementException;

/**
 * Iterator over colors used for visualizing different 
 * architectural regions. The iterator has an iteration
 * step that is an integer which is used as a difference
 * between the colors.
 * 
 * @author svetoslavganov@gmail.com (Svetoslav R. Ganov)
 *
 */
public class ColorIterator implements Iterator<Color> {
	private int[] basicColors;
	private int[] initialColorValues;
	private int colorIndex;
	private int step;
	
	/**
	 * Creates a new instance with a default step
	 * of 15.
	 */
	public ColorIterator() {
		this.step = 15;
		setDefaultInitialColorValues();
		reset();
	}

	/**
	 * Creates a new instance.
	 * 
	 * @param step The iteration step.
	 */
	public ColorIterator(int step) {
		this.step = step;
		setDefaultInitialColorValues();
		reset();
	}
	
	/**
	 * Creates a new instance.
	 * 
	 * @param step The iteration step.
	 * @param initialColorValues The initial values for the red,
	 *        green, and blue components of the color.
	 */
	public ColorIterator(int step, int [] initialColorValues) {
		this.step = step;
		this.initialColorValues = initialColorValues;
		reset();
	}
	
	/**
	 * Resets the red, green, and blue components of the color
	 * to their initial values.
	 */
	public void reset() {
		basicColors = new int[3];
		for (int i = 0; i < 3; i++) {
			basicColors[i] = initialColorValues[i];
		}
	}
	
	/**
	 * @see Iterator#hasNext()
	 */
	public boolean hasNext() {
		return basicColors[0] > 0 || basicColors[1] > 0 || basicColors[2] > 0;
	}

	/**
	 * @see Iterator#next()
	 */
	public Color next() {
		if (!hasNext()) {
			throw new NoSuchElementException();
		}
		Color color = new Color(basicColors[0], basicColors[1], basicColors[2]);
		int basicColorValue = basicColors[colorIndex];
		basicColorValue = basicColorValue - step;
		if (basicColorValue < 0) {
			basicColorValue = 0;
		}
		basicColors[colorIndex] = basicColorValue;
		colorIndex = (colorIndex + 1) % 3;
		return color;
	}

	/**
	 * @see Iterator#remove()
	 */
	public void remove() {
		/*ingore*/	
	}
	
	/**
	 * Sets the color values to their initial
	 * default values.
	 */
	private void setDefaultInitialColorValues() {
		this.initialColorValues = new int[3];
		for (int i = 0; i < 3; i++) {
			initialColorValues[i] = 255;
		}
	}
}
